﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Phoenix.Xna.Framework.Properties;

namespace Phoenix.Xna.Framework.Components.Compositors
{
    public class CompositorCollection : IDisposableEx
    {
        private Engine _engine;
        private SpriteBatch _spriteBatch;

        public SpriteBatch SpriteBatch
        {
            get { return _spriteBatch; }
            set
            {
                _spriteBatch = value;

                foreach (ICompositor c in Compositors)
                {
                    c.SpriteBatch = value;
                }
            }
        }
        public ComponentCollection Compositors { get; set; }

        public CompositorCollection(Engine engine)
        {
            Compositors = new ComponentCollection();
            _engine = engine;
        }

        public void Add(ICompositor compositor)
        {
            compositor.SpriteBatch = _spriteBatch;
            Compositors.Add(compositor);
        }

        public void Update(GameTime gameTime)
        {
            Compositors.Update(gameTime);
        }

        public void Draw(GameTime gameTime)
        {
            if (Compositors.Count > 0)
            {
                if (_spriteBatch == null)
                {
                    throw new InvalidOperationException(Resources.SpriteBatchNullException);
                }

                FillMode oldFillMode = _engine.GraphicsDevice.RenderState.FillMode;
                _engine.GraphicsDevice.RenderState.FillMode = FillMode.Solid;

                // TODO : Remove once I have figured out which render state is being changed to make the terrain render correctly.
                // SpriteBatch.Begin();
                SpriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront, SaveStateMode.SaveState);
                Compositors.Draw(gameTime);
                SpriteBatch.End();
                _engine.GraphicsDevice.RenderState.FillMode = oldFillMode;
            }
        }

        protected virtual void Dispose(bool disposing)
        {
            foreach (IComponent c in Compositors)
            {
                c.Dispose();
            }
        }

        #region IDisposableEx Members

        public bool IsDisposed { get; protected set; }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
